import Ajax from '@mtjs/ajax';
import axios from 'axios';
import { isPlainObject } from 'lodash-es';
import { Toast, Dialog } from 'vant';
import { store } from '@/store';
import { i18n } from '@/plugins/locale';
import { session } from '@/plugins/storage';
import { setSubmitToken, getSubmitToken, getUserToken, SUBMIT_TOKEN } from './submit-token';

const instance = axios.create({
  timeout: 60 * 1000,
  maxRedirects: 3,
  withCredentials: false,
});

const toLoginPage = () => {
  const router = store.$router;
  if (router.currentRoute?.name !== 'login') {
    // 登录失效时，可回到第三方的首页
    const homeUrl = session.get('homeUrl') || '';
    const next = encodeURIComponent(homeUrl || router.currentRoute?.fullPath);
    const query = {
      next,
    };
    router.replace({ name: 'login', query });
  }
};

// ----------------- 拦截器
instance.interceptors.request.use(
  function (config) {
    const siteName = config.params?.site || store.getters['app/site'];
    const extraData = { _site: siteName, _siteType: 'mobile', clientVersion: '1.1.1' };

    // token
    const submitToken = getSubmitToken();
    if (submitToken) {
      config.headers[SUBMIT_TOKEN] = submitToken;
    }
    const accessToken = getUserToken();
    if (accessToken) {
      config.headers['C-Access-Token'] = accessToken;
    }
    // locale
    config.headers.Language = i18n.locale;

    if (isPlainObject(config.data)) {
      config.data = { ...config.data, ...extraData };
    }
    config.params = { ...config.params, ...extraData };
    return config;
  },
  function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  },
);

// 添加响应拦截器
instance.interceptors.response.use(
  function (response) {
    const submitToken = response.headers[SUBMIT_TOKEN];
    setSubmitToken(submitToken);

    const data = response.data;

    if (data.responseStatusCode === 400) {
      const errData = {
        code: data.content.code,
        message: data.content.text,
      };
      return Promise.reject(errData);
    } else {
      return data;
    }
  },
  function (error) {
    if (!error.response) return Promise.reject(error);
    const submitToken = error.response.headers[SUBMIT_TOKEN];
    setSubmitToken(submitToken);

    const { data } = error.response;
    return Promise.reject(data);
  },
);

const createAjax = Ajax({
  axios: instance,
  // post请求的数据类型
  dataType: 'json',
  // 根据不同框架来显示和隐藏 Loading
  loading: {
    show: () => {
      Toast.loading({
        message: i18n.tv('common.tips.api_loading', '加载中'),
        duration: 0,
        forbidClick: true,
      });
    },
    hide: () => {
      Toast.clear();
    },
  },
  // 统一的异常处理
  catch: (err) => {
    // 未登录 或 登录失效
    // eslint-disable-next-line no-console
    console.dir(err);
    if (err.code === 'EX_1_2_USER_01_01_007') {
      toLoginPage();
      return;
    }

    let message = (err.message || err.text || i18n.tv('common.tips.server_error', '服务器繁忙，请稍候再试')).substring(
      0,
      100,
    );

    const isTimeOut = message.indexOf('timeout') > -1;
    const isNetworkError = message.indexOf('Network Error') > -1;

    if (isTimeOut) message = i18n.tv('common.tips.server_timeout', '服务响应超时');
    if (isNetworkError) message = i18n.tv('common.tips.server_error', '服务器繁忙，请稍候再试');

    Dialog.alert({ message }).then(() => {
      if (err.code === 'EX_1_2_USER_01_01_002') {
        window.history.back(-1);
      }
    });
  },
});

export default createAjax;
